/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/6/21 10:50
  *
  * @file       pd_usart.h
  * @brief      Header file of Xxx hardware driver.
  *
  * @note       This file contains the Xxx object declaration.
  *
  * @warning    None.
  ******************************************************************************
  * Change Logs:
  *   Date          Author       Notes
  *   2024/6/21     Chris        the first version
  *
  ******************************************************************************
  */


#ifndef JLC_SKY_USART_H
#define JLC_SKY_USART_H

#include "stm32f407xx.h"
#include "pd_gpio.h"

struct USARTVtbl;

/** @defgroup Object properties
  * @{
  */
typedef struct {
    USART_TypeDef *USARTx;
    GPIOList *gpioList;

    uint8_t rxFlag;
    uint8_t rxData;

    uint32_t BaudRate;
    uint32_t DataWidth;
    uint32_t StopBits;
    uint32_t Parity;
    uint32_t TransferDirection;
    uint32_t HardwareFlowControl;
    uint32_t OverSampling;

    // USART virtual table
    struct USARTVtbl *vptr;
} USART;
/**
 * @}
 */

/** @defgroup Object virtual table definition
  * @{
  */
struct USARTVtbl {
    void (*init)(const USART *this, IRQn_Type irQnType, uint32_t PreemptPriority, uint32_t SubPriority);

    void (*send_byte)(const USART *this, uint8_t byte);

    void (*send_array)(const USART *this, const uint8_t *array, uint16_t length);

    void (*send_string)(const USART *this, char *String);

    void (*send_num)(const USART *this, uint32_t number, uint8_t length);

    void (*printf)(const USART *this, char *format, ...);

    uint8_t (*get_rx_flag)(USART *this);
};
/**
 * @}
 */

/** @defgroup Object constructor and member function declaration
  * @{
  */
void USART_constructor(USART *this, USART_TypeDef *USARTx, GPIOList *gpioList, uint32_t BaudRate);
/**
 * @}
 */

/** @defgroup Object virtual table function implementation
  * @{
  */
static inline void USART_init(const USART *this, IRQn_Type irQnType, uint32_t PreemptPriority, uint32_t SubPriority) {
    this->vptr->init(this, irQnType, PreemptPriority, SubPriority);
}

static inline void USART_sendString(const USART *this, char *String) {
    this->vptr->send_string(this, String);
}

static inline void USART_printf(const USART *this, char *format, ...) {
    char result[256] = {0};
    va_list arg;

    va_start(arg, format);
    vsprintf(result, format, arg);
    va_end(arg);

    this->vptr->send_string(this, result);
}

static inline uint8_t USART_getRxFlag(USART *this) {
    return this->vptr->get_rx_flag(this);
}

/**
 * @}
 */


#endif //JLC_SKY_USART_H
